<!--dateType 1:年月日，2：年月，3：年，4：时-分，5：年月日时分-->
<template>
  <div :class="['sel-input', 'date', { 'name-input': name }]">
    <span v-if="name">{{ name }}</span>
    <el-popover trigger="click" width="320px" ref="popoverRef">
      <template #reference>
        <el-input
          type="text"
          @focus="inputFocus"
          @blur="inputBlur"
          :suffix-icon="Calendar"
          v-model="val"
          placeholder="请选择"
          readonly
        />
      </template>
      <div class="sel-date" tabindex="99" @blur="dateBlur" @mousedown="dateMD">
        <template v-if="active != 4">
          <div class="sd-top">
            <a class="a-prev" @click="pnClick(-1)"></a>
            <!-- <a class="a-ym" @click="ymClick">{{ top }}</a> -->
            <a class="a-ym">{{ top }}</a>
            <a class="a-next" @click="pnClick(1)"></a>
          </div>
          <div class="list-day" v-if="active == 1 || active == 5">
            <div class="week">
              <span v-for="w in week" :key="w">{{ w }}</span>
            </div>
            <div class="days">
              <a
                :class="['a-day', { active: getDayActive(d) }]"
                v-for="d in days"
                :key="d"
                :style="{ marginLeft: d == 1 ? DFstyle : '6px' }"
                @click="dayClick(d)"
              >
                {{ d }}
              </a>
            </div>
          </div>
          <div class="list-month" v-else-if="active == 2">
            <a
              :class="['a-month', { active: i + 1 == month }]"
              v-for="(m, i) in monthArr"
              :key="m"
              @click="monthClick(i)"
            >
              {{ m }}
            </a>
          </div>
          <div class="list-year" v-else-if="active == 3">
            <a
              :class="['a-year', { active: yCloud(y) }]"
              v-for="y in yearArr"
              :key="y"
              @click="yearClick(y)"
            >
              {{ y }}
            </a>
          </div>
        </template>
        <div class="hhmm" v-if="dateType == 4 || active == 6">
          <div class="hh" v-show="hms == 1">
            <a
              v-for="a in 24"
              :key="a"
              :style="hhPst(a)"
              :class="{ active: a == parseInt(hhmm[0]) }"
              @click="hhClick(a)"
            >
              <span :style="hhtRt(a)">{{ a == 24 ? '00' : a }}</span>
            </a>
            <span class="a-line" :style="hhlPst"></span>
          </div>
          <div class="mm" v-show="hms == 2">
            <a
              v-for="a in 59"
              :key="a"
              :style="mmPst(a)"
              :class="{ active: a == parseInt(hhmm[1]) }"
              @click="mmClick(a)"
            >
              <span :style="mmtRt(a)">{{ a < 10 ? '0' + a : a }}</span>
            </a>
            <a :style="mmPst(0)" :class="{ active: hhmm[1] == '00' }" @click="mmClick(0)">
              <span :style="mmtRt(0)">00</span>
            </a>
            <span class="a-line" :style="mmlPst"></span>
          </div>
        </div>
        <div class="hmsave" v-if="dateType == 4">
          <span>
            时:
            <a @click="hms = 1">{{ hhmm[0] }}</a>
          </span>
          <span>
            分:
            <a @click="hms = 2">{{ hhmm[1] == 60 ? '00' : hhmm[1] }}</a>
          </span>
          <a @click="mmClick(-1)">确定</a>
        </div>
        <div class="ymdhmsave" v-if="dateType == 5">
          <a @click="active = 5">
            {{
              year + '-' + month.toString().padStart(2, '0') + '-' + day.toString().padStart(2, '0')
            }}
          </a>
          <a @click="changeType5">{{ hhmm.join(':') }}</a>
          <a @click="mmClick(-1)">确定</a>
        </div>
      </div>
    </el-popover>
  </div>
</template>
<script lang="ts" name="LeoDate" setup>
import { ref, computed, watch } from 'vue'
import { Calendar } from '@element-plus/icons-vue'
interface Props {
  name?: string
  selVal?: string
  selObj?: Object | null
  selKey?: string
  dateType: number
  modelValue?: string | number
  sp?: string
}

const props = withDefaults(defineProps<Props>(), {
  sp: '-',
  modelValue: '',
  name: '',
  dateType: 1,
  selVal: '',
  selObj: null,
  selKey: 'id',
})

const popoverRef = ref()

const emit = defineEmits(['update:modelValue'])

const nowDate = new Date()

const val = ref(props.modelValue)
const evTag = ref('')
const year = ref(nowDate.getFullYear())
const month = ref(nowDate.getMonth() + 1)
const day = ref(nowDate.getDate())
const ys = ref(0)
const hhmm = ref([] as any)
const hms = ref(1)
const active = ref(props.dateType)
const week = ['日', '一', '二', '三', '四', '五', '六']
const monthArr = [
  '1月',
  '2月',
  '3月',
  '4月',
  '5月',
  '6月',
  '7月',
  '8月',
  '9月',
  '10月',
  '11月',
  '12月',
]

const top = computed(() => {
  if (active.value == 1 || active.value == 5) {
    return year.value + ' 年 ' + month.value.toString().padStart(2, '0') + '月'
  } else if (active.value == 2) {
    return year.value + ' 年 '
  } else if (active.value == 3) {
    return ys.value + ' 年 ' + ' - ' + (ys.value + 11) + ' 年 '
  } else if (active.value == 4) {
    return ys.value + ' - ' + (ys.value + 119)
  }
  return ''
})

const days = computed(() => {
  if ([1, 3, 5, 7, 8, 10, 12].indexOf(month.value) >= 0) return 31
  else if ([4, 6, 9, 11].indexOf(month.value) >= 0) return 30
  else {
    if ((year.value % 4 == 0 && year.value % 100 != 0) || year.value % 400 == 0) return 29
    else return 28
  }
})

const yearArr = computed(() => {
  let result = new Array(12).fill(0)
  if (active.value == 3) {
    result = result.map((o, i) => ys.value + i)
  } else if (active.value == 4) {
    result = result.map((o, i) => i * 10 + ys.value + '-' + (i * 10 + ys.value + 9))
  }
  return result
})

const DFstyle = computed(() => {
  let df = new Date(year.value, month.value - 1, 1).getDay()
  return 40 * df + 6 + 'px'
})

const hhlPst = computed(() => {
  let hh = parseInt(hhmm.value[0]),
    h12 = hh < 13 ? hh : hh - 12,
    rt = (h12 - 1) * 30 - 60,
    w = hh < 13 ? 78 : 48
  return {
    transform: 'rotate(' + rt + 'deg)',
    width: w + 'px',
  }
})

const mmlPst = computed(() => {
  let mm = parseInt(hhmm.value[1]),
    rt = mm * 6 - 90
  return {
    transform: 'rotate(' + rt + 'deg)',
  }
})
const inputFocus = () => {
  if (evTag.value == 'imd') {
    evTag.value = ''
  }
}

const inputBlur = () => {
  if (evTag.value != 'lmd') {
    popoverRef.value.hide()
  }
}
const dateMD = () => {
  evTag.value = 'lmd'
}
const dateBlur = () => {
  popoverRef.value.hide()
}
const pnClick = (i: number) => {
  console.log('当前类型', active.value)
  if (active.value < 3) year.value += i
  else if (active.value == 3) ys.value += i * 12
  else if (active.value == 4) ys.value += i * 120
  else if (active.value == 5) {
    if (i == 1) {
      if (month.value >= 12) {
        year.value += i
        month.value = 1
      } else {
        month.value += i
      }
    } else if (i == -1) {
      if (month.value <= 1) {
        year.value += i
        month.value = 12
      } else {
        month.value += i
      }
    }
  }
}

const ymClick = () => {
  if (active.value < 3) active.value += 1
  if (active.value == 3) ys.value = year.value - 4
  else if (active.value == 4) ys.value = parseInt(year.value.toString().substring(0, 3) + '1') - 40
  else if (active.value == 5) active.value = 1
}
const monthClick = (v: number) => {
  month.value = v + 1
  if (props.dateType == 2) {
    val.value = [year.value, month.value.toString().padStart(2, '0')].join(props.sp)
    popoverRef.value.hide()
    return
  }
  active.value = 1
  // if (props.dateType == 3) {
  //   val.value = [
  //     year.value,
  //     month.value.toString().padStart(2, "0"),
  //     day.value.toString().padStart(2, "0")
  //   ].join(props.sp)
  //   active.value += 1
  // } else if (props.dateType == 5) {
  //   active.value = 1
  //   val.value =
  //     [
  //       year.value,
  //       month.value.toString().padStart(2, "0"),
  //       day.value.toString().padStart(2, "0")
  //     ].join(props.sp) +
  //     " " +
  //     hhmm.value.join(":")
  // }
}
const yearClick = (v: number) => {
  if (active.value == 3) {
    year.value = v
    if (props.dateType == 3) {
      val.value = v
      popoverRef.value.hide()
    } else active.value--
  } else {
    active.value--
    ys.value = parseInt(v.toString().split('-')[0])
  }
}
const dayClick = (d: number) => {
  day.value = d
  if (props.dateType == 5) {
    active.value = 6
  } else {
    val.value = [
      year.value,
      month.value.toString().padStart(2, '0'),
      day.value.toString().padStart(2, '0'),
    ].join(props.sp)
    popoverRef.value.hide()
  }
}

const changeType5 = () => {
  active.value = 6
  hms.value = 1
}
const date = (t: number) => {
  let date = new Date(),
    year = date.getFullYear(),
    month = (date.getMonth() + 1).toString().padStart(2, '0'),
    dd = date.getDate().toString().padStart(2, '0'),
    hm =
      date.getHours().toString().padStart(2, '0') +
      ':' +
      date.getMinutes().toString().padStart(2, '0')
  return t == 1 ? hm : [year, month, dd].join(props.sp) + (t == 2 ? ' ' + hm : '')
}

const getDayActive = (d: number) => {
  let sd = [
      year.value,
      month.value.toString().padStart(2, '0'),
      d.toString().padStart(2, '0'),
    ].join(props.sp),
    cv = val.value
      ? props.dateType == 5
        ? val.value.toString().split(' ')[0]
        : val.value
      : date(1)
  return sd == cv
}
const yCloud = (y: number | string) => {
  y += ''
  if (y.toString().indexOf('-').toString().length > 0) {
    let arr = y.toString().split('-')
    if (parseInt(arr[0]) <= year.value && parseInt(arr[1]) >= year.value) return true
    else return false
  } else return y == year.value
}

const hhPst = (i: number) => {
  let h12 = i < 13 ? i : i - 12,
    rt = h12 * 30 - 90,
    tx = i < 13 ? 108 : 75
  return {
    transform: 'rotate(' + rt + 'deg) translate(' + tx + 'px)',
  }
}
const hhtRt = (i: number) => {
  let h12 = i < 13 ? i : i - 12,
    rt = 60 - (h12 - 1) * 30
  return {
    transform: 'rotate(' + rt + 'deg)',
  }
}
const mmPst = (i: number) => {
  let rt = i * 6 - 90
  return {
    transform: 'rotate(' + rt + 'deg) translate(82px)',
  }
}
const mmtRt = (i: number) => {
  let rt = 90 - i * 6
  return {
    transform: 'rotate(' + rt + 'deg)',
  }
}
const hhClick = (a: number) => {
  hhmm.value = [a < 10 ? '0' + a : a, hhmm.value[1]]
  hms.value = 2
}
const mmClick = (a: number) => {
  if (a > 0) hhmm.value[1] = a < 10 ? '0' + a : a
  val.value =
    (props.dateType == 4
      ? ''
      : [
          year.value,
          month.value.toString().padStart(2, '0'),
          day.value.toString().padStart(2, '0'),
        ].join(props.sp) + ' ') + hhmm.value.join(':')
  popoverRef.value.hide()
}

const setValue = () => {
  let v: string | number = ''
  hms.value = 1
  if (props.dateType == 4) {
    //时、分
    v = val.value || date(1)
    hhmm.value = v.toString().split(':')
  } else {
    v = val.value || date(2)
    if (props.dateType == 5) {
      hhmm.value = v.toString().split(' ')[1].split(':')
    }
    let darr = v.toString().split(props.sp)
    year.value = parseInt(darr[0])
    ys.value = year.value - 4
    if ([1, 2, 5].includes(props.dateType)) month.value = parseInt(darr[1])
    if ([1, 5].includes(props.dateType)) day.value = parseInt(darr[2])
  }
}

setValue()

watch(
  () => props.modelValue,
  (v) => {
    val.value = v || ''
    setValue()
  },
)
watch(
  () => val.value,
  (v) => {
    // if (props.selObj && props.selKey) props.selObj[props.selKey] = v
    emit('update:modelValue', v)
  },
)
</script>
<style>
.sel-date {
  --input-border-color: #bbb;
  --input-border: solid 1px var(--input-border-color);
  --input-height: 32px;
  --select-bg: #fcfcfc;
  --select-color: #04bbb7;
}
</style>
<style scoped>
.sel-list {
  position: absolute;
  top: 32px;
  margin-top: 2px;
  right: 0;
  left: 0;
  height: auto;
  border: var(--input-border);
  background: var(--select-bg);
  z-index: 9;
}
.sel-list .scroll-con {
  display: block;
  padding: 2px;
  overflow: hidden;
  max-height: 166px;
}
.sel-list li {
  display: block;
  line-height: 30px;
  margin: 1px 0;
  padding: 0 14px;
}
.sel-input:before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 32px;
  border-left: var(--input-border);
}
.sel-input.name-input:before {
  border-left: var(--name-input-border);
}
.name-input .sel-list {
  left: 80px;
}
/* form -> select */
.sel-input.select input {
  padding-right: 40px;
}
.sel-input.select:after {
  content: '';
  position: absolute;
}
.sel-input.select:after {
  color: var(--input-border-color);
  border-top: solid 5px;
  border-left: solid 6px transparent;
  border-right: solid 6px transparent;
  right: 16px;
  top: 50%;
  transform: translate(50%, -50%);
}
.select > .sel-list li:hover {
  background: #f3f3f3;
}
.select > .sel-list li.active {
  color: var(--select-color);
}
/* form -> sel-date */
.sel-input.date i {
  pointer-events: none;
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translate(50%, -50%);
  background: url('date.png');
  width: 12px;
  height: 12px;
}
.sel-input.date .sel-date {
  position: absolute;
  background: var(--select-bg);
  border: var(--input-border);
  width: 254px;
  left: 0;
  top: var(--input-height);
  margin-top: 2px;
  font-size: 14px;
  z-index: 99;
  color: var(--font-color);
}
.name-input.sel-input.date .sel-date {
  right: 0;
  left: unset;
}
.sd-top {
  line-height: 45px;
  display: flex;
  align-content: stretch;
  align-items: stretch;
}
.sd-top .a-prev,
.sd-top .a-next {
  width: 50px;
  color: var(--input-border-color);
  display: flex;
  align-items: center;
  justify-content: center;
}
.sd-top .a-prev:hover,
.sd-top .a-next:hover {
  color: var(--select-color);
}
.sd-top .a-prev:before,
.sd-top .a-next:before {
  content: '';
  display: inline-block;
  vertical-align: top;
  width: 8px;
  height: 8px;
  border-left: solid 1px;
  border-bottom: solid 1px;
}
.sd-top .a-prev:before {
  transform: rotate(45deg);
}
.sd-top .a-next:before {
  transform: rotate(-135deg);
}
.sd-top .a-ym {
  flex: 1;
  overflow: hidden;
  text-align: center;
}
.list-day {
}
.list-day > .week {
  height: 30px;
  padding: 0 10px;
  background: #ededed;
}
.list-day > .week > span {
  width: 33px;
  line-height: 30px;
  text-align: center;
  display: inline-block;
  vertical-align: top;
  margin-left: 6px;
  color: #666;
  text-align: center;
}
.list-day > .week > span:first-child {
  margin-left: 0;
}
.list-day > .days {
  padding: 10px 10px 4px 4px;
}
.list-day > .days > a {
  width: 33px;
  height: 33px;
  margin-left: 6px;
  margin-bottom: 6px;
  border-radius: 17px;
  display: inline-block;
  vertical-align: top;
  text-align: center;
  line-height: 28px;
  cursor: pointer;
}
.list-day > .days > a.enable {
  color: #5b7f8c;
}
.list-day > .days > a.enable:hover {
  background: none;
  cursor: default;
}
.list-month,
.list-year {
  padding: 20px 37px 12px 37px;
}
.list-month > a,
.list-year > a {
  width: 42px;
  height: 42px;
  text-align: center;
  line-height: 42px;
  display: inline-block;
  vertical-align: top;
  margin: 0 47px 8px 0;
  border-radius: 21px;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
}
.ly2 > a {
  font-size: 12px;
  line-height: 16px;
  padding: 4px;
}
.list-month > a:nth-child(3n),
.list-year > a:nth-child(3n) {
  margin-right: 0;
}
.list-day > .days > a:hover,
.list-month > a:hover,
.list-year > a:hover {
  background: var(--select-li-hover-bg);
}
.list-day > .days > a.active,
.list-month > a.active,
.list-year > a.active {
  background: var(--select-color);
  color: #fff;
}
.hhmm {
  width: 260px;
  height: 260px;
  position: relative;
  background: #ebebeb;
  border-radius: 130px;
  margin: 17px;
}
.hh,
.mm {
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -15px;
  margin-top: -15px;
}
.hh > a,
.mm > a {
  position: absolute;
  width: 30px;
  height: 30px;
  border-radius: 15px;
  transform-origin: center center;
}
.hh > a > span,
.mm > a span {
  width: 30px;
  height: 30px;
  text-align: center;
  line-height: 30px;
  position: absolute;
  transform-origin: center center;
}
.hh > a:nth-child(n + 13) {
  font-size: 12px;
  color: #888;
}
.hh > a:hover {
  background: #ddd;
}
.hh:after,
.mm:after {
  content: '';
  height: 8px;
  width: 8px;
  background: var(--select-color);
  border-radius: 4px;
  position: absolute;
  top: 11px;
  left: 11px;
}
.hh > a.active {
  background: var(--select-color);
  color: #fff;
}
.a-line {
  position: absolute;
  height: 1px;
  transform-origin: left top;
  background: var(--select-color);
  top: 15px;
  left: 15px;
}
.mm {
  margin-top: -5px;
  margin-left: -14px;
}
.mm > a,
.mm > a span {
  height: 10px;
  width: 28px;
  line-height: 10px;
}
.mm > a {
  font-size: 0;
}
.mm > a:nth-child(5n) {
  font-size: 14px;
}
.mm > a > span {
  pointer-events: none;
  z-index: 19;
  margin-left: 14px;
}
.mm:after {
  left: 10px;
  top: 1px;
}
.mm > a:before {
  content: '';
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 2px;
  top: 3px;
  left: 12px;
  pointer-events: none;
  background: #ddd;
  z-index: 20;
}
.mm > a:nth-child(5n):before {
  width: 8px;
}
.mm > a:after {
  content: '';
  position: absolute;
  width: 28px;
  height: 28px;
  border-radius: 14px;
  top: -9px;
  left: 0;
  pointer-events: none;
  z-index: -1;
}
.mm > a:hover {
  z-index: 17;
}
.mm > a:hover:after {
  z-index: 1;
  background: rgba(0, 0, 0, 0.1);
}
.mm > a:hover:before {
  background: var(--select-color);
}
.mm > a.active,
.mm > a.active:hover {
  color: var(--select-color);
}
.mm > a.active:before,
.mm > a.active:hover:before {
  background: var(--select-color);
}
.mm .a-line {
  width: 82px;
  top: 5px;
  left: 14px;
}
.hmsave,
.ymdhmsave {
  height: 41px;
  border-top: var(--input-border);
  line-height: 40px;
  display: flex;
  justify-content: space-around;
}
.hmsave > span {
  width: 70px;
  display: flex;
  justify-content: center;
  align-items: center;
  padding-left: 10px;
}
.hmsave > span > a {
  height: 25px;
  line-height: 24px;
  margin-left: 8px;
  padding: 0 6px;
  border-bottom: solid 1px var(--select-color);
  color: var(--select-color);
}
.hmsave > a {
  width: 52px;
  color: var(--select-color);
  text-align: center;
}
.ymdhmsave > a {
  padding: 0 10px;
}
.ymdhmsave > a:nth-child(2) {
  margin-right: 20px;
}
body {
  background: #f3f3f3;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.title {
  line-height: 80px;
  font-size: 32px;
  font-weight: bold;
  color: #555;
}
.container {
  flex: 1;
  overflow: hidden;
  width: 1320px;
  margin: 30px 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.row1 {
  margin-bottom: 15px;
}
.row1 {
  display: flex;
  align-items: stretch;
}
.col {
  width: 50%;
  border-radius: 5px;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.col:first-child {
  margin-right: 15px;
}
.col:last-child {
  margin-left: 25%;
}
.col-title {
  line-height: 50px;
  font-weight: bold;
  font-size: 18px;
  color: #777;
  padding-left: 20px;
}
.col-con {
  flex: 1;
  padding: 20px;
}
.row {
  height: 42px;
  padding: 5px 0;
  display: flex;
  line-height: 32px;
}
.row > .key {
  width: 132px;
  text-align: right;
  padding-right: 18px;
}
.row > .val {
  flex: 1;
  padding-right: 52px;
}
.row-console {
  margin-top: 50px;
}
.row-console textarea {
  width: 100%;
  height: 120px;
}
</style>
